package com.bamboo.core.annotations.aspect;

import com.bamboo.core.annotations.RecordReqLogAnnotation;
import com.bamboo.core.domain.request.RequestLogEntity;
import com.bamboo.core.exceptions.BambooException;
import com.bamboo.core.util.AnnotationUtil;
import com.bamboo.core.util.RequestUtil;
import com.bamboo.core.util.TimeUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.util.ContentCachingRequestWrapper;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;

/**
* @description 处理RecordReqLog注解
* @date 2025/3/7 15:05
* @author chenzh
*/
@Aspect
@Component
public class RecordReqAnnotationAspect {
    final Logger logger = LoggerFactory.getLogger(RecordReqLogAnnotation.class);

    @Pointcut("@annotation(com.bamboo.core.annotations.RecordReqLogAnnotation)")
    public void anchor(){}

    @Before("anchor()")
    public void handle(JoinPoint joinPoint) {
        RequestLogEntity requestLog = new RequestLogEntity();
        requestLog.setDatetime(TimeUtil.nowDatetimeWithMillis());
        // 获取注解的信息
        try {
            RecordReqLogAnnotation annotation = (RecordReqLogAnnotation) AnnotationUtil.getMethodLevelAnnotation(joinPoint, RecordReqLogAnnotation.class);
            requestLog.setName(annotation.value());
        } catch (BambooException e) {
            logger.error("提取注解({})信息失败", RecordReqLogAnnotation.class, e);
        }

        // 从request中获取相关信息
        HttpServletRequest request = ((ServletRequestAttributes)
                RequestContextHolder.currentRequestAttributes()).getRequest();

        this.getParams(request, requestLog);
        requestLog.setUri(request.getRequestURI());
        requestLog.setIp(RequestUtil.getClientIp(request));
        requestLog.setMethod(request.getMethod());

        logger.info("request info: {}", requestLog);
    }

    private void getParams(HttpServletRequest request, RequestLogEntity requestLog) {
        requestLog.setQuery(request.getQueryString());
        if (request instanceof ContentCachingRequestWrapper) {
            ContentCachingRequestWrapper wrappedRequest = (ContentCachingRequestWrapper) request;

            // 读取缓存内容
            String requestBody;
            try {
                requestBody = new String(
                        wrappedRequest.getContentAsByteArray(),
                        request.getCharacterEncoding()
                );
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }

            requestLog.setBody(requestBody);
        }
    }
}
